package fileby.model.impl.sources.impl;

import fileby.model.impl.sources.FileItem;
import fileby.core.SourceType;
import fileby.core.IDisplayableFileSource;
import fileby.util.properties.IPropertyBundleProvider;
import fileby.util.properties.PropertyBundle;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.filechooser.FileSystemView;

/**
 *
 * @author Daniel
 */
public class SearchSource extends AbstractFileSource {

    private String text;
    private IPropertyBundleProvider propertyBundleProvider;

    public SearchSource(String text, IPropertyBundleProvider propertyBundleProvider,
            List<FileItem> files) {
        sourceType = SourceType.SEARCH;
        this.propertyBundleProvider = propertyBundleProvider;
        this.text = text.toLowerCase();
        changePermission = true;
        name = text + "...";
        PropertyBundle p = this.propertyBundleProvider.create(this.getClass());
        icon = p.getIcon("searchIcon.icon");

        for (FileItem file : files) {
            search(file.getFile());
        }

        if (files.isEmpty()) {
            setText("No search results");
        }

    }

    /**
     * Set the text to search after in the filesystem.
     * @param text
     */
    public void setText(String text) {
        this.text = text;
        name = text + "...";
    }

    /**
     * A recursive algorithm for searching in a folder. The method search
     * both in the current folder and in its all subfolders.
     *
     * @param file the file where to start the searching.
     */
    public void search(File file) {
        // The algorithm for recursive searching was found on
        // www.vafer.org/blog/20071112204524
        if (file.isDirectory() && FileSystemView.getFileSystemView().isTraversable(file)) {
            checkName(file);
            File[] fileList = file.listFiles();
            try {
                for (File f : fileList) {
                    search(f);
                }
            } catch (NullPointerException e) {
                e.getMessage();
            }
        } else {
            checkName(file);
        }
    }

    /**
     * A method which compare a filename with a string object
     *
     * @param file the file to be compared
     */
    public void checkName(File file) {
        if (((file.getName().toLowerCase()).indexOf(text)) > -1) {
            boolean fileNotAdded = true;
            for (FileItem f : files) {
                if (f.getFile().equals(file)) {
                    fileNotAdded = false;
                }
            }
            if (fileNotAdded) {
                files.add(new FileItem(file));
            }
        }
    }

    public IDisplayableFileSource getParent() {
        return null;
    }

    public String getAbsolutePath() {
        return null;
    }

    public boolean addFiles(List<File> fileList, int action) {
        return false; //No need to update
    }

    /**
     * Update the result hits. If the text to search after has been changed before
     * this method is used, this method will clean up among the old hits and pick
     * out the hits that matches the new text string.
     */
    public void updateContent() {
        ArrayList<FileItem> fileList = new ArrayList<FileItem>(files);
        files.clear();
        for (FileItem file : fileList) {
            search(file.getFile());
        }
    }
}
